package com.chang.soul.conf;


import com.chang.soul.bean.Audience;
import com.chang.soul.exception.ResultCode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSONObject;
import com.chang.soul.util.JwtTokenUtil;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * token验证拦截器
 * @author xiaoqingyang@vip.henu.edu.cn
 * @date 2021/3/24
 */

public class JwtInterceptor extends HandlerInterceptorAdapter{
    private static Logger log = LoggerFactory.getLogger(JwtInterceptor.class);
    @Autowired
    private Audience audience;

    /**处理掉跨域请求
     *
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    	response.setHeader("Access-Control-Allow-Origin", "*");
    	response.setHeader("Cache-Control","no-cache");
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        String allowHeaders = "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With, Authorization";
    	response.addHeader("Access-Control-Allow-Headers", allowHeaders);


        // 忽略带JwtIgnore注解的请求, 不做后续token认证校验
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;

            JwtIgnore jwtIgnore = handlerMethod.getMethodAnnotation(JwtIgnore.class);
            if (jwtIgnore != null) {
                return true;
            }
        }

        if (HttpMethod.OPTIONS.equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }

        // 获取请求头信息authorization信息
        final String authHeader = request.getHeader(JwtTokenUtil.AUTH_HEADER_KEY);
        log.info("## authHeader= {}", authHeader);

        if (StringUtils.isBlank(authHeader) || !authHeader.startsWith(JwtTokenUtil.TOKEN_PREFIX)) {
            log.info("### 用户未登录，请先登录 ###");
            JSONObject result = new JSONObject();
            result.put("status", ResultCode.FAIL);
            result.put("statusCode", ResultCode.FAIL.code());
            result.put("describe", ResultCode.USER_NOT_LOGGED_IN.message());
            JSONObject object = new JSONObject();
            object.put("token", "");
            result.put("datas", object);
            response.setCharacterEncoding("UTF-8");
            response.getWriter().println( result.toJSONString());
          //throw new ExceptUtil();
         return false;
        }

        // 获取token
        final String token = authHeader.substring(9);

        if(audience == null){
            BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
            audience = (Audience) factory.getBean("audience");
        }

        // 验证token是否有效--无效已做异常抛出，由全局异常处理后返回对应信息
        Object ob= JwtTokenUtil.parseJWT(token, audience.getBase64Secret());
        if (ob instanceof String) {
			   response.setCharacterEncoding("UTF-8");
		       response.getWriter().println(ob.toString());
		       return false;
		}

        return true;
    }

}

